
package com.idealighter.game.games.fqzs.struct;

import com.google.common.collect.EvictingQueue;

import com.idealighter.game.games.common.AbstractTable;
import com.idealighter.game.games.fqzs.manager.SharkMgr;
import com.idealighter.utils.code.RandCodeUtil;

import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.ScheduledFuture;

import lombok.Data;
import lombok.EqualsAndHashCode;

/**
 * 飞禽走兽桌子 .
 * 
 * @date 2016年2月17日 上午11:55:19
 *
 */
@Data
@EqualsAndHashCode(callSuper = true)
public class SharkTable extends AbstractTable {
  // 所属房间
  private final SharkRoom room;
  // 座位(数目固定)
  private final List<SharkSeat> seats;
  // 系统座位
  private final SharkSeat sysSeat;
  // 当前庄家
  private SharkSeat banker;
  // 申请庄家玩家(定长10队列)
  private final EvictingQueue<Long> applyBankers;
  // 历史中奖图标(定长20队列)
  private final EvictingQueue<Integer> historyRewardIcons = EvictingQueue.create(20);
  // 牌桌的合计押注(每次都从seats计算，导致押注耗时超该10毫秒)
  private final Map<Integer, Long> tableBets = new HashMap<>();
  // 游戏所属步骤(0:休息，1:下注，2:游戏中)
  private SharkTableStatus status = SharkTableStatus.REST;
  // 图标方案
  private int iconPlan = 0;
  // 图标倍率
  private Map<Integer, Integer> iconRates = new HashMap<>();
  // 游戏步骤(休息、下注、开奖、结算)定时Future
  public ScheduledFuture<?> stepFuture = null;
  // 中奖图标
  private int rewardIcon;
  // 中奖排行榜
  private List<TopRewardItem> topRewards = new LinkedList<TopRewardItem>();
  private static final Integer maxTopRewardNum = 5;

  /**
   * .
   * 
   * @param playerId 玩家id.
   * @param nickName .
   * @param chips .
   */
  public void addTopTopReward(Long playerId, String nickName, Long chips) {
    TopRewardItem item = new TopRewardItem();
    item.setId(playerId);
    item.setChips(chips);
    item.setNickName(nickName);

    topRewards.add(item);
    topRewards.sort((e1, e2) -> e2.getChips().intValue() - e1.getChips().intValue());

    int size = topRewards.size();
    // 如果超过限制，删除最后一项
    if (size > maxTopRewardNum) {
      topRewards.remove(size - 1);
    }
  }

  public List<TopRewardItem> getTopRewards() {
    return topRewards;
  }

  public void clearTopReward() {
    topRewards.clear();
  }

  @Data
  public static class TopRewardItem {
    private Long id;
    private String nickName;
    private Long chips;
  }

  /**
   * 构造函数 .
   * 
   * @param id .
   * @param room .
   * @param chairs .
   * @param applyBankerNum 申请庄家人数
   */
  public SharkTable(int id, SharkRoom room, int chairs, int applyBankerNum) {
    super(id);
    this.room = room;
    List<SharkSeat> seats = new ArrayList<>(chairs);
    for (int i = 0; i < chairs; i++) {
      seats.add(new SharkSeat(i, this));
    }
    this.seats = Collections.unmodifiableList(seats);
    this.applyBankers = EvictingQueue.create(applyBankerNum);

    SharkSeat sysSeat = new SharkSeat(-1, this);
    sysSeat.setPlayerId(0);
    this.sysSeat = sysSeat;
    randSysBankerInfo();
    this.banker = sysSeat;
  }

  /**
   * 随机系统庄家信息.
   * 
   * @Title randSysBankerInfo.
   * @author houdongsheng
   * @date 2018年1月30日 下午4:55:07
   */
  public void randSysBankerInfo() {
    if (sysSeat != null) {
      sysSeat.setPlayerId(0);
      sysSeat.setBankerNum(0);
      sysSeat.setTotalChips(RandCodeUtil.random(5 * 100000000L, 10 * 100000000L));
      String oldPlayerName = sysSeat.getPlayerName();
      String newPlayerName = randBankerName();
      while (newPlayerName.equals(oldPlayerName)) {
        newPlayerName = randBankerName();
      }
      sysSeat.setPlayerName(newPlayerName);
    }

  }

  private String randBankerName() {
    List<String> list = Arrays.asList("我的良心喂过狗", "你还梦不梦", "猪，耳朵", "菇凉ザ凄凉", "半疯不傻", "〆青春献给了牌桌", //
        "〆青春献给了牌桌茶凉言尽", "茶凉言尽", "茶凉言尽", "一张婊子脸", "゛吻く 偏了", //
        "放开那尼姑", "妹纸别胸我", "油腻少年", "轻衫萦住", "轻衫萦住", //
        "弃我不顾@", "[ 囍当爹！]", "上天入地く", "飘飘欲仙゛", "时间会咬人", //
        "中发白", "精神囚犯", "冷却的留言", "乞怜相伴゛", "佑你喜乐");

    return RandCodeUtil.randomList(list);
  }

  /**
   * 玩家合计总下注 .
   * 
   * @return
   */
  public long playerTotalBets() {
    long playerTotalBets = 0;
    for (SharkSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Long bet : seat.getBets().values()) {
        if (!seat.isRobot()) {
          playerTotalBets += bet;
        }
      }
    }

    return playerTotalBets;
  }

  /**
   * 所有玩家某个图标合计总下注 .
   * 
   * @return
   */
  public Map<Integer, Long> playerIconBets() {
    Map<Integer, Long> playerIconBets = new HashMap<>();
    for (SharkSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.getBets().entrySet()) {
        if (!seat.isRobot()) {
          int icon = seatBetEtr.getKey();
          long playerIconBet = playerIconBets.getOrDefault(icon, 0L);
          playerIconBet += seatBetEtr.getValue();
          playerIconBets.put(icon, playerIconBet);
        }
      }
    }

    return playerIconBets;
  }

  /**
   * 机器人合计总下注 .
   * 
   * @return
   */
  public Map<Integer, Long> robotIconBets() {
    Map<Integer, Long> robotIconBets = new HashMap<>();
    for (SharkSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Entry<Integer, Long> seatBetEtr : seat.getBets().entrySet()) {
        if (seat.isRobot()) {
          int icon = seatBetEtr.getKey();
          long robotIconBet = robotIconBets.getOrDefault(icon, 0L);
          robotIconBet += seatBetEtr.getValue();
          robotIconBets.put(icon, robotIconBet);
        }
      }
    }

    return robotIconBets;
  }

  /**
   * 机器人某个图标合计总下注 .
   * 
   * @return
   */
  public Long robotTotalBets() {
    long robotTotalBets = 0;
    for (SharkSeat seat : seats) {
      if (seat.getPlayerId() == 0) {
        continue;
      }
      for (Long bet : seat.getBets().values()) {
        if (seat.isRobot()) {
          robotTotalBets += bet;
        }
      }
    }

    return robotTotalBets;
  }

  /**
   * 中飞禽的最大奖励筹码 .
   * 
   * @return
   */
  public long maxFeiQinReward() {
    long feiQinBet = tableBets.getOrDefault(SharkMgr.FEI_QIN, 0L);
    long maxFeiQinReward = feiQinBet * SharkMgr.FEI_QIN_RATE;

    long maxReward = 0;
    for (Integer feiqin : SharkMgr.FEI_QINGS) {
      long reward = tableBets.getOrDefault(feiqin, 0L) * iconRates.getOrDefault(feiqin, 0);
      if (reward > maxReward) {
        maxReward = reward;
      }
    }

    return maxFeiQinReward + maxReward;
  }

  /**
   * 中走兽的最大奖励筹码 .
   * 
   * @return
   */
  public long maxZouShouReward() {
    long feiQinBet = tableBets.getOrDefault(SharkMgr.ZOU_SHOU, 0L);
    long maxFeiQinReward = feiQinBet * SharkMgr.ZOU_SHOU_RATE;

    long maxReward = 0;
    for (Integer zousou : SharkMgr.ZOU_SHOUS) {
      long reward = tableBets.getOrDefault(zousou, 0L) * iconRates.getOrDefault(zousou, 0);
      if (reward > maxReward) {
        maxReward = reward;
      }
    }

    return maxFeiQinReward + maxReward;
  }

  @SuppressWarnings("unchecked")
  @Override
  public SharkRoom room() {
    return room;
  }

  @Override
  public List<SharkSeat> seats() {
    return seats;
  }
}
